#ifndef LUCNX_MEMORY_H
#define LUCNX_MEMORY_H

#include <Lucnx/types.h>
#include <Lucnx/bitmap.h>
#include <Lucnx/list.h>

#define PAGE(address) (address & 0xFFFFF000)
#define PAGE_SIZE 0x1000

#define KERNEL_MEM_SIZE 0x800000
#define KERNEL_MEMORY   0x000000

#define USER_MEM_SIZE   0x8000000
#define USER_MEMORY     0x800000
#define USER_MEM_END    (USER_MEM_SIZE + USER_MEMORY)
#define USER_STACK      USER_MEM_END
#define USER_STACK_TOP (USER_MEM_END + PAGE_SIZE * 4)

typedef struct virtual_addrs
{
    u32 vaddr_start;
    bitmap_t bitmap;
}_packed virtual_addrs;

typedef struct block_desc_t
{
    u16 size;
    list free_list;
}block_desc_t;

typedef struct arena_t
{
    block_desc_t *desc;
    int nr;
    bool is_page;
}arena_t;

typedef enum pool_flag
{
    PF_KERNEL = 0,
    PF_USER
}pool_flag;

typedef struct ards_t
{
    u64 base;
    u64 length;
    u32 type;
}_packed ards_t;

void page_map(void *vaddr, void *paddr);
void *addr_v2p(void *vaddr);

void *kpage_alloc(int count);
void kpage_free(void *page, int count);

void *kmalloc(u16 _Size);
void kfree(void *address);

int sys_brk(void *brk);

void arena_init(block_desc_t *dir);

void build_task_stack3();
void free_pde();

#endif